<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>angularjs双向绑定</title>
    <link rel="stylesheet" href="../css/reveal/reveal.css">

    <!-- PPT主题，可以在/css/reveal/theme/中选择其他主题，目前暂时只能使用该模板 -->
    <link rel="stylesheet" href="../css/reveal/theme/ptt.css">

    <!-- syntax highlighting 代码高亮主题 -->
    <link rel="stylesheet" href="../lib/reveal/css/zenburn.css">

    <!-- 打印和PDF输出样式 -->
    <script>
        var link = document.createElement('link');
        link.rel = 'stylesheet';
        link.type = 'text/css';
        link.href = window.location.search.match(/print-pdf/gi) ? '../css/reveal/print/pdf.css' : '../css/reveal/print/paper.css';
        document.getElementsByTagName('head')[0].appendChild(link);
    </script>
</head>
<body>
<img src="../img/demo/logo.png" alt="" usemap="#pttmap" class="base-logo">
<map name="pttmap">
    <area shape="rect" coords="0,0,276,58" href="http://www.jnshu.com" alt="" target="_blank"/>
</map>
<div class="reveal">
    <div class="slides">
        <section>
            <h3>angularjs双向绑定后，发生了什么事情？view层和controller层是如何进行绑定的？</h3>
            <h3>成都小课堂</h3>
            <p>分享人：童海琴</p>
        </section>
        <section>
            <p>目录</p>
            <p>1.背景介绍</p>
            <p>2.如何绑定</p>
            <p>3.如何实现</p>
            <p>4.常见问题</p>
            <p>5.解决方案</p>
            <p>6.更多讨论</p>
            <p>7.参考文献</p>
        </section>

        <section>
            <h3>1.背景介绍</h3>
          <p style="text-align: left">双向绑定，是从界面的操作能实时反映到数据，数据的变更也能
                    实时展现到界面</p>
        </section>
        <section>
            <h3>如何绑定</h3>
        </section>
        <section>
            如果我们自己实现双向数据绑定该怎么写？
        </section>
        <section>
            <section>
                <h3>如何实现</h3>
            </section>

            <section style="text-align: left;font-size: 30px">
                <p>angular是一个MVVM（Model-View，View-Model）模式的框架。</p>
                <p>MVC:View 传送指令到 Controller；Controller 完成业务逻辑后，要求 Model 改变状态；
                    Model 将新的数据发送到 View；所有通信都是单向的
                </p>
                <p>MVVM它采用双向绑定：View的变动，自动反映在 ViewModel，反之亦然。</p>
                <p>View是angularjs编译html后呈现出来的，需要编译的是controller中的定义的属性和方法以及directive中定义的指令。</p>
                <p>View和controller是独立开来的，他们之间的纽带就是scope。Controller负责向scope中提供属性和方法，
                    便于和view层面的html进行交互。</p>

            </section>
            <section>
              <p>Angular双向绑定通过$watch,$digest，$apply实现的。</p>
            </section>
            <section>
              <h3>watch序列</h3>
              <p>watch监控model中是否有变化，会记录last值，也就是改变后的值，每一个model都会增加一个watch到watch队列中。</p>
            </section>
            <section>
              <h3>digest循环</h3>
              <p>当浏览器接收到可以被angular context处理的事件时，$digest循环就会触发，这个循环有两个子循环，
                  一个处理evalAsync队列，另一个处理watch队列，$digest会遍历$watch</p>

            </section>
            <section style="text-align: left;">
              <p>既然所有的$watch都检查完了，那就要问了：有没有$watch更新过？如果有至少一个更新过，这个循环就会再次触发，
                  直到所有的$watch都没有变化。这样就能够保证每个model都已经不会再变化。记住如果循环超过10次的话，
                  它将会抛出一个异常，防止无限循环。 当$digest循环结束时，DOM相应地变化。</p>
              <p>每一个进入angular context的事件都会执行一个$digest循环，也就是说每次我们输入一个字母循环都会检查整个页面的所有$watch。</p>
            </section>
            <section>
                <h3>4.常见问题</h3>
                <p>$digest和$apply有何区别？干嘛不直接使用$digest?</p>
            </section>

            <section>
                <h3>5.解决方法</h3>
            </section>

            <section style="text-align: left;font-size: 35px">
                <p>这里值虽然改变了，但是没有强制执行$degest,watch根本没有执行</p>
                <p>一般带ng的事件angular都会给你自动添加好了apply，但是你要操纵事件的时候加上aplly才能实现数据输出到view层中。</p>
                <p>
                    为什么在ng-click里面调用$digest的话，会报错呢？因为Angular的设计，同一时间只允许一个$digest运行，
                    而ng-click这种内置指令已经触发了$digest，当前的还没有走完，所以就出错了
                </p>
                <p>当你传入一个function到$apply()中的时候，这个function会被包装到一个try…catch块中，所以一旦有异常发生，
                    该异常会被$exceptionHandler service处理。
                </p>
            </section>
            <section>
                <p>1.$apply可以带参数，它可以接受一个函数，然后在应用数据之后，调用这个函数。</p>
                <p>2.当调用$digest的时候，只触发当前作用域和它的子作用域上的监控，但是当调用$apply的时候，会触发作用域树上的所有监控。</p>
            </section>
            </section>
        <section>
            <h3>6.更多讨论</h3>
            <p>提问环节</p>
        </section>
        <section>
            <h3>7.参考文献</h3>
            <a href="http://www.cnblogs.com/bigdataZJ/p/AngularjsInAction2.html">view和controller的那些事儿</a>
            <a href="https://github.com/xufei/blog/issues/10">Angular沉思录（一）数据绑定</a>
            <a href="http://www.angularjs.cn/A0a6">理解$watch ，$apply 和 $digest --- 理解数据绑定过程</a>
        </section>
        <section>
            <h2>鸣谢</h2>
            <p>感谢大家观看</p>
            <p>
                <small>BY : 刘天云|李维文|王奎智|童海琴</small>
            </p>
        </section>
    </div>
</div>

<script src="../lib/reveal/js/head.min.js"></script>
<script src="../lib/reveal/reveal.js"></script>

<script>
    // 以下为常见配置属性的默认值
    // {
    // 	controls: true, // 是否在右下角展示控制条
    // 	progress: true, // 是否显示演示的进度条
    // 	slideNumber: false, // 是否显示当前幻灯片的页数编号，也可以使用代码slideNumber: 'c / t' ，表示当前页/总页数。
    // 	history: false, // 是否将每个幻灯片改变加入到浏览器的历史记录中去
    // 	keyboard: true, // 是否启用键盘快捷键来导航
    // 	overview: true, // 是否启用幻灯片的概览模式，可使用"Esc"或"o"键来切换概览模式
    // 	center: true, // 是否将幻灯片垂直居中
    // 	touch: true, // 是否在触屏设备上启用触摸滑动切换
    // 	loop: false, // 是否循环演示
    // 	rtl: false, // 是否将演示的方向变成RTL，即从右往左
    // 	fragments: true, // 全局开启和关闭碎片。
    // 	autoSlide: 0, // 两个幻灯片之间自动切换的时间间隔（毫秒），当设置成 0 的时候则禁止自动切换，该值可以被幻灯片上的 ` data-autoslide` 属性覆盖
    // 	transition: 'default', // 切换过渡效果，有none/fade/slide/convex/concave/zoom
    // 	transitionSpeed: 'default', // 过渡速度，default/fast/slow
    // 	mouseWheel: true, //是否启用通过鼠标滚轮来切换幻灯片
    // }
    // 初始化幻灯片
    Reveal.initialize({
        history: true,
        dependencies: [
            {src: '../plugin/markdown/marked.js'},
            {src: '../plugin/markdown/markdown.js'},
            {src: '../plugin/notes/notes.js', async: true},
            {
                src: '../plugin/highlight/highlight.js', async: true, callback: function () {
                hljs.initHighlightingOnLoad();
            }
            }
        ]
    });
</script>
</body>
</html>
Contact GitHub API Training Shop Blog About
© 2016 GitHub, Inc. Terms Privacy Security Status He
